package com.panopset.net.ftp;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Vector;
import static com.panopset.Util.*;

public class FTPCommandSocket extends AbstractSocket {
    public static final int FTP_CMD_PORT = 21;
    private BufferedReader reader;
    private BufferedWriter writer;

    FTPCommandSocket(String host) throws IOException {
        super(host, FTP_CMD_PORT);
        dspmsg("Connected to " + host);
        String response = readLine();
        if (!response.startsWith("220 ")) {
            throw new IOException(
                    "FtpOp received an unknown response when connecting to the FTP server: "
                            + response);
        }
    }

    String sendVerify(String command, String result) throws IOException {
        return sendVerify(command, new String[] { result });
    }

    String sendVerify(String command, String... results) throws IOException {
        String r = getCommandResponse(command);
        for (String s : results) {
            if (r.startsWith(s)) {
                return r;
            }
        }
        throw new IOException("Unexpected result: " + r);
    }

    BufferedReader getReader() throws IOException {
        if (this.reader == null) {
            reader = new BufferedReader(new InputStreamReader(getSocket()
                    .getInputStream()));
        }
        return this.reader;
    }

    BufferedWriter getWriter() throws IOException {
        if (this.writer == null) {
            writer = new BufferedWriter(new OutputStreamWriter(getSocket()
                    .getOutputStream()));
        }
        return this.writer;
    }

    String getCommandResponse(String command) throws IOException {
        sendCommandLine(command);
        return readLine();
    }

    String readLine() throws IOException {
        Vector<String> lines = getCommandResponses();
        if (lines == null) {
            throw new IOException("null response.");
        }
        if (lines.size() < 1) {
            dspmsg("No response");
            return "";
        }
        for (int i = 0; i < lines.size() - 1; i++) {
            dspmsg("Ignoring message: " + lines.elementAt(i));
        }
        return lines.elementAt(lines.size() - 1);
    }

    void sendCommandLine(String line) throws IOException {
        getWriter().write(line + getReturnChar());
        getWriter().flush();
        dspmsg("> " + line);
    }

    Vector<String> sendCommand(String line) throws IOException {
        sendCommandLine(line);
        dspmsg("> " + line);
        return getCommandResponses();
    }

    Vector<String> getCommandResponses() throws IOException {
        Vector<String> rtn = new Vector<String>();
        int count = 0;
        while (!getReader().ready() && count++ < 20) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                log(e);
            }
        }
        while (getReader().ready()) {
            rtn.add(getReader().readLine());
        }
        for (String s : rtn) {
            dspmsg("< " + s);
        }
        return rtn;
    }
}
